package ch.exm.storm.collections;

import java.util.Collection;
import java.util.Map;
import java.util.Set;

public abstract class AbstractBidirectionalMap<K, V> implements BidirectionalMap<K, V> {

	private Map<K, V> directMap;
	private Map<V, K> reverseMap;

	protected AbstractBidirectionalMap(Map<K, V> directMap, Map<V, K> reverseMap) {
		this.directMap = directMap;
		this.reverseMap = reverseMap;
	}

	public Map<V, K> getReversemap() {
		return reverseMap;
	}

	public void clear() {
		directMap.clear();
		reverseMap.clear();
	}

	public boolean containsKey(Object key) {
		return directMap.containsKey(key);
	}

	public boolean containsValue(Object value) {
		return reverseMap.containsKey(value);
	}

	public Set<java.util.Map.Entry<K, V>> entrySet() {
		return directMap.entrySet();
	}

	public V get(Object key) {
		return directMap.get(key);
	}

	public K getKey(Object value) {
		return reverseMap.get(value);
	}

	public boolean isEmpty() {
		return directMap.isEmpty();
	}

	public Set<K> keySet() {
		return directMap.keySet();
	}

	public V put(K key, V value) {
		if (containsKey(key)) {
			V originalValue = directMap.get(key);
			reverseMap.remove(originalValue);
		}
		if (containsValue(value)) {
			K originalKey = reverseMap.get(value);
			directMap.remove(originalKey);
		}
		directMap.put(key, value);
		reverseMap.put(value, key);
		return directMap.put(key, value);
	}

	public void putAll(Map<? extends K, ? extends V> t) {
		for (K key : t.keySet())
			put(key, t.get(key));
	}

	public V remove(Object key) {
		V value = directMap.remove(key);
		reverseMap.remove(value);
		return value;
	}

	public int size() {
		return directMap.size();
	}

	public Collection<V> values() {
		return directMap.values();
	}
}
